package org.bootstrap.annotation.impl;


import cn.hutool.core.lang.Console;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.bootstrap.annotation.RedisCacheStr;
import org.bootstrap.tool.RedisTool;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

@SuppressWarnings("unused")
@Component
@Aspect
public class RedisCacheStrImpl {

    @Resource
    private RedisTool redisTool;

    @Pointcut("@annotation(org.bootstrap.annotation.RedisCacheStr)")
    public void pointcut() {
    }

    @ExceptionHandler(Exception.class)
    @Around(value = "@annotation(org.bootstrap.annotation.RedisCacheStr)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        String res = null;
        if (ObjectUtil.isNotNull(redisTool)) {
            Signature signature = joinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            RedisCacheStr saveToRedisCache = methodSignature.getMethod().getAnnotation(RedisCacheStr.class); // 获取方法上的注解
            String key = saveToRedisCache.key();// 获取key
            if (redisTool.hasKey(key)) {
                res = redisTool.get_string(key);
            } else {
                String[] params = methodSignature.getParameterNames();
                Object[] args = joinPoint.getArgs();
                HashMap<String, Object> map = new HashMap<>();
                for (int i = 0; i < params.length; i++) {
                    map.put(params[i], args[i]);
                }
                long time = saveToRedisCache.time();
                TimeUnit unit = saveToRedisCache.unit();
                Object origin = joinPoint.proceed();// 返回的数据
                String _key = StrUtil.toString(map.get(key));
                redisTool.save_string(_key, origin.toString(), time, unit);
                res = redisTool.get_string(_key);
            }
        } else {
            Console.error("redis 初始化bean异常: {}", redisTool);
        }
        return res;
    }

    @After("@annotation(org.bootstrap.annotation.RedisCacheStr)")
    public void after(JoinPoint joinPoint) {

    }
}
